package com.jialea.luobochat.server.service.impl;

import com.jialea.luobochat.common.exception.MinIOException;
import com.jialea.luobochat.common.utils.file.FilePathUtils;
import com.jialea.luobochat.server.config.properties.MinIOProperties;
import com.jialea.luobochat.server.service.MinIOService;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author: wf
 * @created: 2024/6/22 22:09
 */
@Slf4j
@Service
public class MinIOServiceImpl implements MinIOService {
    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinIOProperties minIOProperties;

    private final static String separator = "/";


    /**
     * 上传图片文件
     *
     * @param filename    文件名
     * @param contentType 文件类型
     * @param inputStream 文件
     * @return 文件全路径
     */
    public String uploadImgFile(String filename, String contentType, InputStream inputStream) {
        try {
            String filePath = FilePathUtils.builderFilePath(filename);
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object(filePath)
                    .contentType(contentType)
                    .bucket(minIOProperties.getBucket()).stream(inputStream, inputStream.available(), -1)
                    .build();
            minioClient.putObject(putObjectArgs);
            StringBuilder urlPath = new StringBuilder(minIOProperties.getDomain());
            urlPath.append(separator + minIOProperties.getBucket());
            urlPath.append(separator);
            urlPath.append(filePath);
            return urlPath.toString();
        } catch (Exception e) {
            log.error("minio上传图片失败，错误原因：{}", e.getMessage());
            throw new MinIOException("上传图片失败，请稍后再试");
        }
    }

    /**
     * 上传html文件
     *
     * @param filename    文件名
     * @param inputStream 文件流
     * @return 文件全路径
     */
    @Override
    public String uploadHtmlFile(String filename, InputStream inputStream) {
        try {
            String filePath = FilePathUtils.builderFilePath(filename);
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object(filePath)
                    .contentType("text/html")
                    .bucket(minIOProperties.getBucket()).stream(inputStream, inputStream.available(), -1)
                    .build();
            minioClient.putObject(putObjectArgs);
            StringBuilder urlPath = new StringBuilder(minIOProperties.getDomain());
            urlPath.append(separator + minIOProperties.getBucket());
            urlPath.append(separator);
            urlPath.append(filePath);
            return urlPath.toString();
        } catch (Exception e) {
            log.error("minio上传html文件失败，错误原因：{}", e.getMessage());
            throw new MinIOException("上传失败，请稍后再试");
        }

    }

    /**
     * 删除文件
     *
     * @param pathUrl 文件全路径
     */
    @Override
    public void delete(String pathUrl) {
        try {
            String key = pathUrl.replace(minIOProperties.getDomain() + separator, "");
            int index = key.indexOf(separator);
            String bucket = key.substring(0, index);
            String filePath = key.substring(index + 1);
            // 删除Objects
            RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
            minioClient.removeObject(removeObjectArgs);
        } catch (Exception e) {
            log.error("minio删除文件失败，pathUrl：{}，错误原因：{}", pathUrl, e.getMessage());
            throw new MinIOException("删除失败，请稍后再试");
        }

    }


    /**
     * 下载文件
     *
     * @param pathUrl 文件全路径
     * @return 文件流
     */
    @Override
    public byte[] downLoadFile(String pathUrl) {
        String key = pathUrl.replace(minIOProperties.getDomain() + separator, "");
        int index = key.indexOf(separator);
        String bucket = key.substring(0, index);
        String filePath = key.substring(index + 1);
        InputStream inputStream = null;
        try {
            inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOProperties.getBucket()).object(filePath).build());
        } catch (Exception e) {
            log.error("minio下载文件失败，pathUrl:{}，错误原因：{}", pathUrl, e.getMessage());
            throw new MinIOException("下载失败，请稍后再试");
        }

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while (true) {
            try {
                if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            byteArrayOutputStream.write(buff, 0, rc);
        }
        return byteArrayOutputStream.toByteArray();
    }


}
